
import { Asset, Component, Constructor, Prefab, SpriteFrame } from "cc";
import { PrefabCfg } from "../../../auto/PrefabCfg";
import { getUIClassBUrl } from "../ui/UIManager";
import { DestroyHook } from "./DestroyHook";

export class ResLoader {
    // private m_Match3ZiUE_Prefab:Prefab = null

    //待加载资源
    private toLoadAssets: { type: Constructor<Asset> | null, bUrl: IBundleUrl }[] = [];
    //已加载的资源
    private loadedAssets: Asset[] = []
    private m_Released: boolean = false

    addUI<UI extends Component>(uiClass: Constructor<UI>) {
        // let prefabBurl = getUIClassBUrl(uiClass);
        // this.toLoadAssets.push({
        //     type: Prefab,
        //     bUrl: prefabBurl
        // })
        
        this.addAsset(getUIClassBUrl(uiClass),Prefab);

        if (typeof uiClass['R'] === "function") {
            (uiClass['R'] as Function).call(uiClass, this);
        }

        return this;
    }


    async load() {
        let toLoadPromises = this.toLoadAssets.map(toLoad => gtr.res.loadAssetAsync(toLoad.bUrl, toLoad.type));
        let toLoadResults = await Promise.all(toLoadPromises);
        toLoadResults.forEach(asset => {
            //资源引用计数
            asset.addRef();
            if (!this.m_Released) {
                this.loadedAssets.push(asset);
            } else {
                asset.decRef(true);
            }
        })


        // this.m_Match3ZiUE_Prefab = await gtr.res.loadAssetAsync(PrefabCfg.Match3ZiUE,Prefab);
        // this.m_Match3ZiUE_Prefab.addRef()
    }


    // 释放已加载资源
    releaseResRef() {

        if (this.m_Released) return;
        this.m_Released = true;
        while (this.loadedAssets.length) {
            this.loadedAssets.pop().decRef();
        }

        // this.m_Match3ZiUE_Prefab.decRef(true)
    }

    autoRelease(comp: Component) {
        comp.node.addComponent(DestroyHook).addHook(() => {
            this.releaseResRef();
        })

        return this;
    }

    addAsset(bUrl: IBundleUrl, type: Constructor<Asset> | null) {
        this.toLoadAssets.push({
            type: type,
            bUrl: bUrl
        });
        return this;
    }

    addSpriteFrame(bUrl:IBundleUrl){return this.addAsset(bUrl,SpriteFrame)}
}